using System;
using System.Threading;
using SecuBat.AttackPlugin;
using SecuBat.Crawling.Forms;
using SecuBat.Modularization.Plugins;
using Css.Diagnostics;
using SecuBat.Logging;

namespace SecuBat.Work
{
	/// <summary>
	/// Summary description for AttackFormTask.
	/// </summary>
	public class ExecuteAttackTask : Task
	{
		private int _attackerRunId;
		private int _attackFormId;
		private Plugin _plugin;
		private ICommonData _commonData;

		public ExecuteAttackTask(int attackerRunId, int attackFormId, Plugin plugin, ICommonData commonData)
		{
			_attackerRunId = attackerRunId;
			_attackFormId = attackFormId;
			_plugin = plugin;
			_commonData = commonData;
		}

		public override void Run()
		{
            base.Run();

			// Initialize
			if (_plugin != null)
			{
                this.Status = TaskStatus.Initializing;
                this.TaskActivity = "Initializing task";
                this.SignalizeStatusChange();

                IAnalysis analysis = _plugin.GetAnalysisInstance(_commonData);
				if (analysis != null)
				{
					IAttack attack = _plugin.GetAttackInstance(_attackerRunId, _attackFormId, _plugin.Id, null, analysis, _commonData);
					Thread.Sleep(1);

					// Executing
                    try
                    {
                        attack.InitializeAttack();
                        Thread.Sleep(1);

                        this.Status = TaskStatus.SendingRequest;
                        this.TaskActivity = "Executing attack";
                        this.Url = attack.AttackForm.ActionAddress.Url;
                        this.SignalizeStatusChange();
                        
                        attack.DoAttack();
                        Thread.Sleep(1);

                        this.Status = TaskStatus.Reporting;
                        this.TaskActivity = "Report attack";
                        this.SignalizeStatusChange();

                        attack.Register();
                        Thread.Sleep(1);

                        this.Status = TaskStatus.AnalyzingResponse;
                        this.TaskActivity = "Analyzing attack";
                        this.SignalizeStatusChange();

                        attack.AnalyzeAttack();
                        Thread.Sleep(1);
                    }
                    catch (Exception ex)
                    {
                        LogManager.Write(TraceLevel.Error, ex, "Attack execution");
                    }

				}


//				// Create an attack without a specified submit button
//				SimpleSqlInsertionAttack attack = new SimpleSqlInsertionAttack(_form, null);
//				attack.Execute();
//
//				Thread.Sleep(1);
//
//				// Create sub-attacks for each button
//				foreach (FormParameter button in _form.Buttons)
//				{
//					if (button.Name.Length > 0)
//					{
//						LogManager.Write(TraceLevel.Information, String.Format("Creating sub-attack using button \"{0}\".", button.Name), "Attack logging");
//						SimpleSqlInsertionAttack subAttack = new SimpleSqlInsertionAttack(_form, button);
//						subAttack.Execute();
//
//						Thread.Sleep(1);
//					}
//				}

			}
			this.Status = TaskStatus.Finished;
            this.SignalizeStatusChange();
		}
	}
}